Skip to content

feat(authz): support 'unscoped' wildcard sentinel in /v1/authz/search#303

Merged
smoreinis merged 5 commits into
mainfrom
feat/authz-search-wildcard-sentinel
Jun 16, 2026
Merged

feat(authz): support 'unscoped' wildcard sentinel in /v1/authz/search#303
smoreinis merged 5 commits into
mainfrom
feat/authz-search-wildcard-sentinel

Conversation

@smoreinis

@smoreinis smoreinis commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Lets an auth provider answer POST /v1/authz/search with the wildcard sentinel { "unscoped": true } to mean all resources of this type, which the Agentex authorization proxy maps onto the existing unscoped path (None → no id IN (...) filter) instead of an enumerated id list.

  • Proxy (adapter_agentex_authz_proxy.py): recognize unscoped: true and return None; otherwise pass items through unchanged.
  • Port (port.py): widen list_resources return type to Iterable[str] | None.
  • Contract doc (auth_provider_contract.md): formalize the unscoped sentinel in the search response schema, the inclusion-filter note, and the endpoint summary.
  • Tests: unit coverage for the four cases.

Motivation

A provider that grants broad access (e.g. a single-account "allow everything" authorization model) previously had to enumerate every accessible id, because items: [] hides everything and there was no "all resources" signal in the contract. Enumeration couples the provider to Agentex's storage and scales poorly on large accounts. The sentinel lets such a provider answer search statelessly.

Design notes

  • Explicit boolean chosen over overloading items: null: a provider must deliberately opt into "everything", and a malformed response missing both fields raises rather than silently failing open.
  • No downstream changes. AuthorizationService.list_resources already returns Iterable[str] | None, and every consumer (DAuthorizedResourceIds, the list routes, the Postgres list filter) already treats None as "no filter" — the path taken when authorization is disabled. The sentinel reuses that exact, already-tested path.
  • The sentinel is opt-in and backward compatible: existing providers returning an items array behave exactly as before.

Test plan

  • New unit tests (tests/unit/adapters/authorization/test_adapter_agentex_authz_proxy.py):
    • { "items": ["a","b"] }["a","b"]
    • { "unscoped": true }None
    • { "unscoped": true, "items": ["x"] }None (unscoped wins)
    • { "items": [] }[] (sentinel not triggered; still hides everything)
  • Existing authz unit suite passes (no regression).

Greptile Summary

This PR adds an explicit wildcard response for authz search results. The main changes are:

  • Maps { "unscoped": true } from /v1/authz/search to None in the authz proxy.
  • Keeps ordinary items responses as the exact inclusion filter.
  • Widens the authorization gateway return type to allow unscoped results.
  • Documents the new auth provider contract behavior.
  • Adds unit coverage for sentinel and fail-closed cases.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.
  • The wildcard path requires the exact JSON boolean sentinel.
  • Malformed search responses still raise instead of opening access.
  • Direct downstream consumers already handle None as the existing no-filter path.

T-Rex T-Rex Logs

What T-Rex did

  • The focused authz search sentinel repro was executed to validate the sentinel handling.
  • The repro exercised items passthrough, empty items, unscoped: true returning None, and unscoped: true winning over items to confirm expected control flow.
  • Truthiness tests confirmed that truthy non-boolean values are not treated as the wildcard sentinel.
  • Malformed responses without both unscoped and items were verified to raise instead of returning an unscoped result.
  • Downstream list-resource consumers were checked to handle None as the existing no-filter path.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (3): Last reviewed commit: "Merge branch 'main' into feat/authz-sear..." | Re-trigger Greptile

@smoreinis smoreinis marked this pull request as ready for review June 11, 2026 20:52
@smoreinis smoreinis requested a review from a team as a code owner June 11, 2026 20:52
- Add fail-closed test: response missing both 'unscoped' and 'items' raises KeyError
- Use an unambiguous truthy-non-boolean value (1) in the strict-sentinel test
@smoreinis smoreinis enabled auto-merge (squash) June 16, 2026 19:40
@smoreinis smoreinis merged commit ab469df into main Jun 16, 2026
31 checks passed
@smoreinis smoreinis deleted the feat/authz-search-wildcard-sentinel branch June 16, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants